Repository navigation
build: add an ANYPS5_ENABLE_TSAN option for ThreadSanitizer builds - #11179
Conversation
Declare a ThreadSanitizer switch next to ANYPS5_ENABLE_ASAN and reject it on other systems and compilers, as ASan does. The two sanitizers cannot share one process, so configuring both is a fatal error.
GCC rejects -fsanitize=thread together with -static ("cannot specify -static with -fsanitize=thread"), and the ThreadSanitizer runtime has to come up before libc. Leave the -static -static-libgcc -static-libstdc++ executable flags out when ANYPS5_ENABLE_TSAN is on, as the ASan branch already does.
Add the ThreadSanitizer compile and link options, keep frame pointers for usable report stacks, and define ANYPS5_ENABLE_TSAN=1 so sources and tests can tell a ThreadSanitizer build apart. The guest arena keeps its default range: it starts below ThreadSanitizer's application memory limit, and the arena already records host mappings such as the runtime's protected gaps as used ranges.
…hreadSanitizer The sanitizer runtimes intercept mlock, munlock, mlockall and munlockall and return 0 without calling the kernel (TSAN_OPTIONS=verbosity=1 prints "ThreadSanitizer ignores mlock/mlockall/munlock/munlockall"). VmLck therefore never grows and mlock of an unmapped or reserved range succeeds, so the ENOMEM and locked-size checks that are already skipped under ANYPS5_ENABLE_ASAN are skipped under ANYPS5_ENABLE_TSAN too.
…ThreadSanitizer CheckMlock reads VmLck and expects ENOMEM from mlock of reserved and unmapped ranges. ThreadSanitizer, like AddressSanitizer, replaces mlock and munlock with interceptors that return 0 without locking anything, so skip the same checks that ANYPS5_ENABLE_ASAN already skips. The guest arena range check stays as is: a ThreadSanitizer build keeps the default range.
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
THEMANnt
left a comment
There was a problem hiding this comment.
Reviewed 52e0132a34e117a197331c66a38a1382b5d3568a. Pending review.
Configuration branches are checked; Linux ThreadSanitizer runtime validation remains pending.
Validation: Executed the submitted CMake guards and flag branches: Linux GNU/Clang select thread sanitizer and dynamic linking; Windows, Darwin, unsupported compiler and ASan+TSan combinations refuse as intended. Source review also covers the sanitizer-specific mlock exclusions and suppressions.
Scope / next step: These are actual CMake branch checks with recorded commands, not native Linux TSan compilation or execution. Please retain that distinction until a supported Linux runtime run is available.
What
The tree can be built with AddressSanitizer (
-DANYPS5_ENABLE_ASAN=ON), but not with ThreadSanitizer, although the runtime is heavily threaded: guest pthreads, AGC queue workers, audio and equeue waiters. This adds-DANYPS5_ENABLE_TSAN=ONfor Linux GCC and Clang builds.ANYPS5_ENABLE_TSANcompiles and links with-fsanitize=thread -fno-omit-frame-pointerand definesANYPS5_ENABLE_TSAN=1. It is rejected with a configure error on other systems or compilers, and when combined withANYPS5_ENABLE_ASAN. Like the ASan build, it keeps executables dynamically linked, because the sanitizer runtime cannot be linked statically.guest_mlockandguest_memoryskip their hostmlockresult checks under ThreadSanitizer, as they already do under ASan. The sanitizer's own mappings change what/proc/self/statusreports and what a locked range can hold.tools/tsan-suppressions.txtsilences reports from Mesa's lavapipe, the LLVM it compiles shaders with, and PulseAudio. Those system libraries are not instrumented, so ThreadSanitizer cannot see their locking. Without the file, 94 AGC tests fail insidelibvulkan_lvp.so. With lavapipe alone suppressed, 705 fail on lock-order reports insidelibLLVM.Results. A full RelWithDebInfo build of this branch on an
ubuntu-latestfork runner (GCC 15.2), withTSAN_OPTIONS=halt_on_error=1:second_deadlock_stack=1:suppressions=tools/tsan-suppressions.txtandctest --timeout 600 --parallel 4: 2,274 tests, 2,112 passed, 88 skipped and 74 failed. The failures, by cause:app0.zarmutex and the directory mutex in libccloseracing an equeue file measurementguest_socket_events)scePthreadAttrGetreading_detachedguest_pthread_stack)Pm4.cpp:581,GuestMemory.cpplabel writes, and the tests that drive them)recv), glibcflockfilearoundputc_unlocked, FFmpeg frame threadingsetcontext,RLIMIT_DATA, SEGVs inagc_driver_graphics*Dispatch.cppstatic profiling counters,libSceJobManagerWorkerEntry, a few test-side plain flags)The option builds nothing differently unless it is turned on, and no workflow runs it yet.
Tested
libLLVM).-DANYPS5_ENABLE_TSAN=ON -DANYPS5_ENABLE_ASAN=ONstops withANYPS5_ENABLE_ASAN and ANYPS5_ENABLE_TSAN cannot be combined, and-DANYPS5_RELINKER_ONLY=ON -DANYPS5_ENABLE_TSAN=ONconfigures.python3 tools/check_conventions.py --base upstream/mainandgit diff --check upstream/mainpass.tools/pr_overlap.py --branchlists only pull requests that shareCMakeLists.txt,docs/dev/BUILD.mdorcore/libs/tests/GuestMemory.cpp, with no conflicting lines. Windows and macOS are rejected by design and were not run.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)